package com.zzw.utils;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.beanutils.converters.IntegerConverter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
 * @project  name  : basic_core
 * @create   time  : 2016-4-5 上午10:09:45  
 * @class    name  : cn.com.basic.common.beanutil.BasePropertyUtils  
 * @modify   list  : (modify by :modify date:modify content)       
 *
 */

@SuppressWarnings("rawtypes")
public class BasePropertyUtils {

	private static Log logger = LogFactory.getLog(BasePropertyUtils.class);

	static {
		ConvertUtils.register(new IntegerConverter(null), Integer.class);
	}

	public static List<String> getSetters(Object bean) {
		List<String> setters = new ArrayList<>();
		PropertyDescriptor[] descriptors = PropertyUtils
				.getPropertyDescriptors(bean);
		for (int i = 0; i < descriptors.length; i++) {
			PropertyDescriptor desc = descriptors[i];
			if (desc.getWriteMethod() != null) {
				String name = desc.getName();
				setters.add(name);
			}
		}
		return setters;
	}

	@SuppressWarnings("unchecked")
	public static String[] getProperties(Object bean) {
		Map map = getPropertiesMap(bean);
		String[] propNames = (String[]) map.keySet().toArray(new String[0]);

		return propNames;
	}

	public static Map getPropertiesMap(Object bean) {
		Map map = null;

		if ((bean instanceof Map))
			map = (Map) bean;
		else {
			try {
				map = PropertyUtils.describe(bean);
			} catch (Exception e) {
				logger.error("获得bean描述信息出错");
				throw new RuntimeException(e);
			}

		}

		map.remove("class");
		return map;
	}



	
	public static  Class getPropertyType(Object bean, String propertyName) {
		Class type = null;
		try {
			if ((bean instanceof Map)) {
				Object value = ((Map) bean).get(propertyName);
				if (value != null)
					type = value.getClass();
			} else {
				type = PropertyUtils.getPropertyType(bean, propertyName);
			}

			return type;
		} catch (Exception e) {
			logger.error("get属�?�类型时出错,属�??:" + propertyName);
			throw new RuntimeException(e);
		}
	}

	public static boolean exists(Object bean, String propertyName) {
		try {
			boolean exists = false;

			if ((bean instanceof Map)) {
				exists = ((Map) bean).containsKey(propertyName);
			} else {
				exists = PropertyUtils.isWriteable(bean, propertyName);
			}

			return exists;
		} catch (Exception e) {
			logger.error("判断属�?�是否存在时出错,属�??:" + propertyName);
			throw new RuntimeException(e);
		}
	}

	public static Object getPropertyValue(Object bean, String propertyName) {
		Object value = null;
		try {
			if (propertyName.indexOf(".") > 0) {
				String[] props = propertyName.split("\\.");
				int n = props.length;
				for (int i = 0; i < n; i++) {
					if (i == 0)
						value = bean;
					if (value == null)
						return null;

					value = getPropertyValue(value, props[i]);
				}
			} else {
				value = PropertyUtils.getProperty(bean, propertyName);
			}
		} catch (NoSuchMethodException e) {
			char ch = propertyName.charAt(1);
			if ((ch >= 'A') && (ch <= 'Z')) {
				propertyName = upperFirstLetter(propertyName);
				try {
					value = PropertyUtils.getProperty(bean, propertyName);
				} catch (IllegalAccessException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (InvocationTargetException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (NoSuchMethodException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}

		} catch (Exception e) {
			if (bean != null) {
				logger.error("�?" + bean.getClass().getName() + " 里get属�?�时出错:"
						+ propertyName);
			}
			throw new RuntimeException(e);
		}

		return value;
	}

	private static String upperFirstLetter(String propertyName) {
		String name = propertyName.substring(0, 1).toUpperCase()
				+ propertyName.substring(1);
		return name;
	}

}
